package com.zqs.compareface.server.local;

import com.zqs.compareface.server.commit.CommitApiOrLocal;
import com.zqs.compareface.utils.impl.ImageToBase64Util;
import com.zqs.compareface.utils.impl.LocalCheckUtil;
import com.zqs.compareface.utils.impl.MyLogUtil;
import com.zqs.compareface.utils.impl.Timer;
import com.zqs.compareface.utils.impl.threadpool.TheCustomDynamicThreadPoolUtil;
import com.zqs.compareface.utils.impl.threadpool.myLinkedBlockingQueue.ReWritedCapacityLinkedBlockingQueue;
import org.opencv.core.Mat;

import java.time.Duration;
import java.time.Instant;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadPoolExecutor;


/**
 * @Program: FaceCompare
 * @Description:
 * @Author: zqs
 * @Create： 2021-08-12-21:10
 */
public class FaceImageContrast {
    //使用线程池
    /**
     * 使用静态线程池
     */
    static ThreadPoolExecutor executor = TheCustomDynamicThreadPoolUtil.buildThreadPoolExecutor();
    static ReWritedCapacityLinkedBlockingQueue reWritedCapacityLinkedBlockingQueue = (ReWritedCapacityLinkedBlockingQueue) executor.getQueue();
    public static void contrast(Mat mat){
        double result = LocalCheckUtil.compare_allimage(mat);
        if (result >= 0.6) {
            MyLogUtil.log("人脸匹配成功，匹配结果："+result);
        }
        if (result > 0.02 && result < 0.6){
            float time = Duration.between(Timer.time, Instant.now()).getSeconds();
            //判断上一次调用接口检测的时间是否小于5秒，如果是，则不再提交
            if (time > 5){
                //检测到人脸，丢入线程池处理
                executor.execute(() ->{

                    String base64code = ImageToBase64Util.convertToBase64(mat);
                    baiduApi(base64code);
                    TheCustomDynamicThreadPoolUtil.threadPoolStatus(executor,"视频处理任务---");
                });
                System.out.println(executor.getActiveCount());
                //线程池调整
                if (executor.getActiveCount() / executor.getMaximumPoolSize() >= 0.7) {
                    //最小核心线程数和最大线程数的值，设置为相同最佳
                    executor.setCorePoolSize(Double.valueOf(Math.round(executor.getCorePoolSize()*1.5)).intValue());
                    executor.setMaximumPoolSize(Double.valueOf(Math.round(executor.getMaximumPoolSize()*1.5)).intValue());
                    executor.prestartAllCoreThreads();
                    reWritedCapacityLinkedBlockingQueue.setCapacity(Double.valueOf(Math.round(reWritedCapacityLinkedBlockingQueue.getCapacity()*1.2)).intValue());
                    TheCustomDynamicThreadPoolUtil.threadPoolStatus(executor, "线程池扩容之后");
                }
                System.out.println(Double.valueOf(Math.round(executor.getActiveCount()*1.5)).intValue());
                if (executor.getActiveCount() / executor.getMaximumPoolSize() < 0.6){
                    //核心线程数是否大于2，如果大于2，判断活跃线程数扩大1.5倍后是否不为0（有可能在程序执行到此刻的时候，唯一一个执行任务的线程已经完成了任务，活跃线程就会为0）
                    //如果核心线程数大于2为真，则核心线程数/2，或通过活跃线程数*1.5进行扩容（条件为，活跃线程数扩大1.5倍后是否为0
                    //如果核心线程数大于2为假，那么直接设定线程数的最低值2  math.round 四舍五入取整
                    executor.setCorePoolSize(executor.getCorePoolSize()>2 ?
                            (Double.valueOf(Math.round(executor.getActiveCount()*1.5)).intValue()==0 ?
                                    Double.valueOf(Math.round(executor.getCorePoolSize()/2)).intValue() :
                                    Double.valueOf(Math.round(executor.getActiveCount()*1.5)).intValue()) : 2);
                    executor.setMaximumPoolSize(executor.getMaximumPoolSize()>2 ?
                            (Double.valueOf(Math.round(executor.getActiveCount()*1.5)).intValue()==0 ?
                                    Double.valueOf(Math.round(executor.getMaximumPoolSize()/2)).intValue() :
                                    Double.valueOf(Math.round(executor.getActiveCount()*1.5)).intValue()) : 2);
                    executor.prestartAllCoreThreads();
                    //如果队列大于5，则进行-5后的结果判断，如果-5后大于等于5，那么执行-5操作，如果大于等于5不成立，则直接修改队列数量为5
                    reWritedCapacityLinkedBlockingQueue.setCapacity(reWritedCapacityLinkedBlockingQueue.getCapacity() >5 ?
                            (Math.max(reWritedCapacityLinkedBlockingQueue.getCapacity() - 5, 5)) : 5);
                    TheCustomDynamicThreadPoolUtil.threadPoolStatus(executor, "线程池收缩之后");
                }
                MyLogUtil.log("本地人脸匹配精准不够，提交百度API检测，本地匹配结果："+result);
            }
            else {
                return;
            }
        }
        if (result <=0.01){
            MyLogUtil.log("人脸匹配未成功,匹配结果："+result);
        }
    }

    public static void baiduApi(String bas64code){
            String userid = "wuyifang";
            CommitApiOrLocal.preparingData(bas64code, userid);

    }

}
